﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Net;
using System.Windows.Media.Animation;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows.Controls.Primitives;
using Microsoft.Windows.Controls;
using System.Data;
using System.Configuration;
using System.ComponentModel;
using System.Runtime.Remoting.Messaging;
using Microsoft.Windows.Controls.Primitives;
using System.Xml;

namespace Cerebrata.CloudStorage.Utilities.FileUploader
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {

        private String[] DelimiterItem = { "{Tab}", "Comma {,}", "Semicolon{;}", "Colon{:}", "Space", "Other" };
        private String[] LineFeedItem = { "{CR}{LF}", "{CR}", "{LF}", "Semicolon{;}", "Comma{,}", "{Tab}", "Vertical Bar{|}" };
        private String[] TextQualiItem = { "Double Quote{\"}", "Quote{'}", "<none>" };
        private String[] SkipLineItem = { "{#}", "Other", "<none>" };
        private String[] MyDataTypeComboBoxList = { "Binary", "Boolean", "DateTime", "Double", "Guid", "Int32", "Int64", "String" };
        private bool HeaderContains = false;
        private String DisplayFile = String.Empty;
        private TextBox DelimOtherTextBox;
        private TextBox SkipOtherTextBox;
        private HeaderData[] HeaderInformation;
        private String[] NewFile;
        private String FileType = String.Empty;

        //List of Column Names which are to be imported

        private List<string> HeaderColumnNames;

        //Delimeters symbol
        string[] LineFeedSymbol = new string[1];
        string[] SkipLineSymbol = new string[1];
        string[] TextQualifySymbol = new string[1];
        string[] DelimSymbol = new string[1];

        private DataTable FileDataTable; // for data Presentation
        private DataTable XMlDataTable;
        private DataTable EavDataTable; // for Eav generation
        private DataTable UploadDataTable;// for show upload process
        private DataRow UploadRow;
        private DataTable UnUploadedDataTable; // for failed data when uploading
        private Storyboard startbusy;
        private Storyboard stopbusy;
        private Regex regex;


        public Window1()
        {
            InitializeComponent();
            regex = new Regex("^[a-z][a-z0-9_]*$", RegexOptions.IgnoreCase);
            Loaded += new RoutedEventHandler(Window1_Loaded);
            startbusy = (Storyboard)this.FindResource("StartBusy");
            stopbusy = (Storyboard)this.FindResource("StopBusy");
        }

        void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            FileSelectionTab.IsSelected = true;
            DisableTabItems(1);
            next_HeaderSpecificationBtn.IsEnabled = false;
            delimeterCbox.ItemsSource = DelimiterItem;
            LineFeedCbox.ItemsSource = LineFeedItem;
            SkipLineCbox.ItemsSource = SkipLineItem;
            textqualifierCbox.ItemsSource = TextQualiItem;
            delimeterCbox.SelectedIndex = 0;
            LineFeedCbox.SelectedIndex = 0;
            SkipLineCbox.SelectedIndex = 2;
            textqualifierCbox.SelectedIndex = 2;
        }

        #region File Selection Tab

        private void FileBrowserBtn_Click(object sender, RoutedEventArgs e)
        {
            //GetFile();
            GetFileAsync();
        }

        private delegate void FileTaskAsync();

        private void GetFileAsync()
        {
            FileTaskAsync FileTaskWorker = new FileTaskAsync(GetFile);
            AsyncCallback FilecompletedCallback = new AsyncCallback(MyFileTaskCompletedCallback);
            AsyncOperation async = AsyncOperationManager.CreateOperation(null);
            FileTaskWorker.BeginInvoke(FilecompletedCallback, null);

        }

        private void MyFileTaskCompletedCallback(IAsyncResult ar)
        {

            this.Dispatcher.Invoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
           new Action(
          delegate()
          {

              FileTaskAsync worker = (FileTaskAsync)((AsyncResult)ar).AsyncDelegate;

              // finish the asynchronous operation


              worker.EndInvoke(ar);
              startbusy.Stop();
              stopbusy.Begin();

          }));


        }

        private void GetFile()
        {

            this.Dispatcher.Invoke(
             System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    OpenFileDialog Filedlg = new OpenFileDialog();
                    Filedlg.Multiselect = false;
                    Filedlg.Filter = "Both Files(*.txt,*.xml)|*.txt;*.xml|Text files(*.txt)|*.txt|Xml Files(*.Xml)|*.xml";
                    if ((bool)Filedlg.ShowDialog())
                    {
                        startbusy.Begin();
                        FileNameTextBox.Text = Filedlg.FileName.ToString();
                        string ext = System.IO.Path.GetExtension(Filedlg.FileName);
                        if (ext == ".txt")
                        {
                            FileType = "TextFile";
                            FileDelimiterStackPanel.IsEnabled = true;
                            DisplayFile = System.IO.File.ReadAllText(Filedlg.FileName, System.Text.Encoding.Default);
                            DisplayFileTextBox1.Text = DisplayFile;
                            DisplayFileTextBox1.SetValue(Grid.RowProperty,4);
                            DisplayFileTextBox1.SetValue(Grid.RowSpanProperty, 1);
                            next_HeaderSpecificationBtn.IsEnabled = true;

                        }
                        else
                        {
                            FileType = "XmlFile";
                            FileDelimiterStackPanel.IsEnabled = false;
                            DisplayFile = System.IO.File.ReadAllText(Filedlg.FileName, System.Text.Encoding.Default);
                            DisplayFileTextBox1.Text = DisplayFile;
                            DisplayXmlFile();
                            DisplayFileTextBox1.SetValue(Grid.RowProperty, 1);
                            DisplayFileTextBox1.SetValue(Grid.RowSpanProperty, 4);
                            //DisplayFileTextBox1.SetValue(Grid.RowProperty, 1);
                            

                         
                            
                        }

                        //StreamReader reader = new StreamReader(Filedlg.FileName);
                       
                       
                    }

                }));
        }

        private void DisplayXmlFile()
        {
            try
            {
                string dataFilePath = FileNameTextBox.Text;
                StringBuilder output = new StringBuilder();
                String xmlString = DisplayFile.ToString();

                XMlDataTable = new DataTable();
                using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
                {
                    XmlWriterSettings ws = new XmlWriterSettings();
                    ws.Indent = true;
                    using (XmlWriter writer = XmlWriter.Create(output, ws))
                    {
                        // Parse the file and display each of the nodes.
                        while (reader.Read())
                        {
                            switch (reader.NodeType)
                            {
                                case XmlNodeType.Element:
                                    writer.WriteStartElement(reader.Name);
                                    break;
                                case XmlNodeType.Text:
                                    writer.WriteString(reader.Value);
                                    break;
                                case XmlNodeType.CDATA:
                                    writer.WriteString(reader.Value);
                                    break;
                                case XmlNodeType.XmlDeclaration:
                                case XmlNodeType.ProcessingInstruction:
                                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                                    break;
                                case XmlNodeType.Comment:
                                    writer.WriteComment(reader.Value);
                                    break;
                                case XmlNodeType.EndElement:
                                    writer.WriteFullEndElement();
                                    break;
                            }
                        }
                    }
                    DisplayFileTextBox1.Text = output.ToString();
                    StringReader theReader = new StringReader(output.ToString());
                    DataSet theDataSet = new DataSet();
                    theDataSet.ReadXml(theReader);

                    for (int k = 0; k < theDataSet.Tables.Count; k++)
                    {
                        XMlDataTable.Merge(theDataSet.Tables[k]);
                    }
                  
                    
                    next_HeaderSpecificationBtn.IsEnabled = true;

                }

            }
            catch (Exception)
            {
                stopbusy.Begin();
                MessageBox.Show("Unexpected XML declaration.", "Error");
                next_HeaderSpecificationBtn.IsEnabled = false;
            }

        }

        private void FileNameTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            DisableTabItems(1);
        }

        private void delimeterCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(1);
            if (delimeterCbox.SelectedIndex == 5)
            {
                DelimOtherTextBox = new TextBox();
                DelimOtherTextBox.Width = 40;
                DelimOtherTextBox.Height = 23;
                DelimOtherTextBox.Margin = new Thickness(0, 0, 0, 1);
                delimPanel.Children.Add(DelimOtherTextBox);
                DelimOtherTextBox.Focus();
            }
            else
            {
                delimPanel.Children.Remove(DelimOtherTextBox);
            }
        }

        private void SkipLineCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(1);
            if (SkipLineCbox.SelectedIndex == 1)
            {
                SkipOtherTextBox = new TextBox();
                SkipOtherTextBox.Width = 40;
                SkipOtherTextBox.Height = 23;
                SkipOtherTextBox.Margin = new Thickness(0, 0, 0, 1);
                SkipPanel.Children.Add(SkipOtherTextBox);
                SkipOtherTextBox.Focus();

            }
            else
            {
                SkipPanel.Children.Remove(SkipOtherTextBox);
            }
        }

        private void LineFeedCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(1);
        }

        private void textqualifierCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(1);
        }

        private void Radioyes_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(1);
        }

        private void RadioNo_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(1);
        }




        #endregion

        #region Header Specification Tab

        private void next_HeaderSpecificationBtn_Click(object sender, RoutedEventArgs e)
        {
            if (FileType == "XmlFile")
            {
                HeaderSpectab.IsEnabled = true;
                HeaderSpectab.IsSelected = true;
                //tab2text.Text = "This file contains headers. Please specify the Azure Data type and check the CheckBox next to the column if you want to import that particular column.";
                HeaderInformation = new HeaderData[XMlDataTable.Columns.Count];

                for (int i = 0; i < XMlDataTable.Columns.Count; i++)
                {
                    HeaderInformation[i] = new HeaderData(XMlDataTable.Columns[i].ToString().Trim(), i, "String", true);
                }

                HeaderDisplayGrid.ItemsSource = HeaderInformation;
            }
            else
            {
                String[] TotalFileRowDisplay;
                String[] TempFile;
                String[] HeaderRow;
                DelimSymbol[0] = GetDelimeterSymbol();
                if (DelimSymbol[0].Equals(String.Empty))
                {
                    MessageBox.Show("Delimiter Symbol cannot be empty", "Error");
                    DelimOtherTextBox.Focus();
                    return;
                }
                LineFeedSymbol[0] = GetLineFeedSymbol();
                TextQualifySymbol[0] = GetTextQualifySymbol();
                SkipLineSymbol[0] = GetSkipLineSymbol();
                if (SkipLineSymbol[0].Equals(String.Empty))
                {
                    if (SkipLineCbox.SelectedIndex == 1)
                    {
                        MessageBox.Show("Skip Line Symbol cannot be empty", "Error");
                        SkipOtherTextBox.Focus();
                        return;
                    }
                }

                try
                {
                    TotalFileRowDisplay = DisplayFile.Split(LineFeedSymbol, StringSplitOptions.RemoveEmptyEntries);
                    TempFile = new string[TotalFileRowDisplay.Length];
                    int index = 0;
                    if (SkipLineCbox.SelectedIndex != 2)
                    {
                        for (int i = 0; i < TotalFileRowDisplay.Length; i++)
                        {
                            if (!TotalFileRowDisplay[i].StartsWith(SkipLineSymbol[0]))
                            {
                                TempFile[index] = TotalFileRowDisplay[i];
                                index++;
                            }
                        }
                        NewFile = new String[index];
                        for (int i = 0; i < index; i++)
                            NewFile[i] = TempFile[i];

                    }
                    else
                    {
                        NewFile = new string[TotalFileRowDisplay.Length];
                        NewFile = TotalFileRowDisplay;
                    }



                    if (textqualifierCbox.SelectedIndex != 2)
                    {
                        //Call Split Method 
                        HeaderRow = Split(NewFile[0], DelimSymbol[0], TextQualifySymbol[0]);

                        for (int i = 0; i < HeaderRow.Length; i++)
                        {
                            //Remove the TextQualifier Symbol from Header
                            HeaderRow[i] = HeaderRow[i].Replace(TextQualifySymbol[0].ToString(), "");
                        }
                    }
                    else
                    {
                        HeaderRow = NewFile[0].Split(DelimSymbol, StringSplitOptions.RemoveEmptyEntries);
                    }


                    HeaderInformation = new HeaderData[HeaderRow.Length];

                    if (Radioyes.IsChecked == true)
                    {
                        HeaderContains = true;

                        tab2text.Text = "This file contains headers. Please specify the Azure Data type and check the CheckBox next to the column if you want to import that particular column.";

                        for (int i = 0; i < HeaderRow.Length; i++)
                        {
                            HeaderInformation[i] = new HeaderData(HeaderRow[i].ToString().Trim(), i, "String", true);
                        }

                    }
                    else
                    {
                        HeaderContains = false;
                        tab2text.Text = "This file does not contain headers.\nPlease specify the Header name, Azure Data type and check the CheckBox next to the column if you want to import that particular column. ";
                        for (int i = 0; i < HeaderRow.Length; i++)
                        {
                            HeaderInformation[i] = new HeaderData("HeaderName" + i.ToString(), i, "String", true);

                        }
                    }

                    HeaderSpectab.IsEnabled = true;
                    HeaderSpectab.IsSelected = true;

                    HeaderDisplayGrid.ItemsSource = HeaderInformation;
                }
                catch (Exception)
                {
                    MessageBox.Show("This File cannot be Parsed.", "Error");
                    return;
                }

            }
        }

        private string GetDelimeterSymbol()
        {
            int index = delimeterCbox.SelectedIndex;
            String DelimSymbol = string.Empty;
            switch (index)
            {
                case 0:
                    DelimSymbol = "\t";
                    break;
                case 1:
                    DelimSymbol = ",";
                    break;
                case 2:
                    DelimSymbol = ";";
                    break;
                case 3:
                    DelimSymbol = ":";
                    break;
                case 4:
                    DelimSymbol = " ";
                    break;
                case 5:

                    if (DelimOtherTextBox.Text.ToString() != null && DelimOtherTextBox.Text.ToString() != string.Empty)
                    {
                        DelimSymbol = DelimOtherTextBox.Text.ToString();
                    }
                    else
                    {
                        DelimSymbol = string.Empty;

                    }
                    break;
            }
            return DelimSymbol;
        }

        private string GetTextQualifySymbol()
        {
            int index = textqualifierCbox.SelectedIndex;
            String TextQualifierSymbol = String.Empty;
            switch (index)
            {
                case 0:
                    TextQualifierSymbol = "\"";
                    break;
                case 1:
                    TextQualifierSymbol = "'";
                    break;
                case 2:
                    TextQualifierSymbol = String.Empty;
                    break;
            }
            return TextQualifierSymbol;

        }

        private string GetSkipLineSymbol()
        {
            int index = SkipLineCbox.SelectedIndex;
            String SkipLineSymbol = String.Empty;

            switch (index)
            {
                case 0:
                    SkipLineSymbol = "#";
                    break;
                case 1:

                    if (SkipOtherTextBox.Text.ToString() != string.Empty && SkipOtherTextBox.Text.ToString() != null)
                    {

                        SkipLineSymbol = SkipOtherTextBox.Text.ToString();
                    }
                    else
                    {

                        SkipLineSymbol = string.Empty;

                    }
                    break;
                case 2:
                    SkipLineSymbol = String.Empty;
                    break;
            }

            return SkipLineSymbol;

        }

        private string GetLineFeedSymbol()
        {

            int index = LineFeedCbox.SelectedIndex;
            String LineFeedSymbol = String.Empty;
            switch (index)
            {
                case 0:
                    LineFeedSymbol = "\r\n";
                    break;
                case 1:
                    LineFeedSymbol = "\r";
                    break;
                case 2:
                    LineFeedSymbol = "\n";
                    break;
                case 3:
                    LineFeedSymbol = ";";
                    break;
                case 4:
                    LineFeedSymbol = ",";
                    break;
                case 5:
                    LineFeedSymbol = "\t";
                    break;
                case 6:
                    LineFeedSymbol = "|";
                    break;

            }
            return LineFeedSymbol;

        }

        private string[] Split(string expression, string delimiter, string qualifier)
        {
            bool _QualifierState = false;
            int _StartIndex = 0;

            List<string> lst = new List<string>();

            for (int _CharIndex = 0; _CharIndex < expression.Length - 1; _CharIndex++)
            {


                if ((qualifier != null)
                 & (string.Compare(expression.Substring(_CharIndex, qualifier.Length), qualifier) == 0))
                {
                    _QualifierState = !(_QualifierState);
                }
                else if (!(_QualifierState) & (delimiter != null)
                      & (string.Compare(expression.Substring(_CharIndex, delimiter.Length), delimiter) == 0))
                {
                    lst.Add(expression.Substring(_StartIndex, _CharIndex - _StartIndex));
                    _StartIndex = _CharIndex + 1;
                }
            }

            if (_StartIndex < expression.Length)
                lst.Add(expression.Substring(_StartIndex, expression.Length - _StartIndex));

            string[] _returnValues = new string[lst.Count];
            lst.CopyTo(_returnValues);
            return _returnValues;
        }

        private void ComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            ComboBox curComboBox = sender as ComboBox;
            curComboBox.ItemsSource = MyDataTypeComboBoxList;
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(2);
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            DisableTabItems(2);
        }

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(2);
        }

        private void HeaderDisplayGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            DisableTabItems(2);
        }

        #endregion

        #region Data Presentation Tab

        private void next_DataPresentation_Click(object sender, RoutedEventArgs e)
        {

            try
            {
                int headerImport = 0;
                for (int i = 0; i < HeaderInformation.Length; i++)
                {
                    //count the total header which are to be imported
                    if (HeaderInformation[i].ToBeImported)
                    {
                        headerImport++;
                        if (HeaderInformation[i].HeaderName.Trim() == String.Empty)
                        {
                            MessageBox.Show("Header name cannot be Empty", "Error");
                            HeaderDisplayGrid.SelectedIndex = i;
                            return;
                        }
                        if (!regex.IsMatch(HeaderInformation[i].HeaderName, 0))
                        {
                            MessageBox.Show("\nInvalid Header name : " + HeaderInformation[i].HeaderName + "\n\nNote :\n\t1. Header name cannot be other than alphanumeric.\n\t2. Header name's first character must be alphabet.\n\t3. Special symbols are not allowed.");
                            HeaderDisplayGrid.SelectedIndex = i;
                            return;
                        }
                    }
                    for (int j = i + 1; j < HeaderInformation.Length; j++)
                    {
                        if (HeaderInformation[i].HeaderName.Trim() == HeaderInformation[j].HeaderName.Trim() && HeaderInformation[i].ToBeImported == true && HeaderInformation[j].ToBeImported == true)
                        {

                            MessageBox.Show("Header Name cannot be same. Please change the Header name or import one of them. ", "Error");
                            //isHeaderImport = false;
                            HeaderDisplayGrid.SelectedIndex = i;
                            return;
                        }
                    }

                }


                if (headerImport == 0)
                {
                    MessageBox.Show("Please Import atleast one Header ", "Error");
                    HeaderDisplayGrid.SelectedIndex = 0;
                    return;
                }
                else
                {
                    HeaderColumnNames = new List<string>();
                    FileDataTable = new DataTable();
                    int CountImportColumn = 0;

                    for (int i = 0; i < HeaderInformation.Length; i++)
                    {
                        if (HeaderInformation[i].ToBeImported)
                        {
                            HeaderColumnNames.Add(HeaderInformation[i].HeaderName.Trim());
                            FileDataTable.Columns.Add(HeaderInformation[i].HeaderName.Trim() + "\n(" + HeaderInformation[i].HeaderDataType + ")");
                            CountImportColumn++;
                        }
                    }


                    if (FileType == "TextFile")
                    {

                        for (int i = 0; i < NewFile.Length; i++)
                        {
                            DataRow newRow = FileDataTable.NewRow();
                            String[] b = new String[HeaderInformation.Length];

                            if (HeaderContains && (NewFile.Length == 1))
                            {
                                MessageBox.Show("No records found.");
                                return;
                            }
                            if (HeaderContains && i == 0) // if Header contains then skip the first row
                            { continue; }



                            if (textqualifierCbox.SelectedIndex != 2)
                            {
                                b = Split(NewFile[i], DelimSymbol[0], TextQualifySymbol[0]);

                                for (int t = 0; t < CountImportColumn; t++)
                                {
                                    b[t] = b[t].Replace(TextQualifySymbol[0].ToString(), "");
                                }
                            }
                            else
                            {
                                if (NewFile[i] != null)
                                {
                                    b = NewFile[i].Split(DelimSymbol, StringSplitOptions.RemoveEmptyEntries);
                                }
                            }
                            int RowIndex = 0;
                            for (int j = 0; j < HeaderInformation.Length; j++)
                            {
                                if (HeaderInformation[j].ToBeImported)
                                {
                                    if (j < b.Length)
                                    {
                                        newRow[RowIndex] = b[j].ToString().Trim();

                                    }
                                    else
                                    {
                                        newRow[RowIndex] = String.Empty;

                                    }
                                    RowIndex++;
                                }
                            }
                            FileDataTable.Rows.Add(newRow);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < XMlDataTable.Rows.Count; i++)
                        {
                            DataRow newRow = FileDataTable.NewRow();
                            DataRow xmlRow = XMlDataTable.Rows[i];

                            int RowIndex = 0;
                            for (int j = 0; j < HeaderInformation.Length; j++)
                            {

                                if (HeaderInformation[j].ToBeImported)
                                {
                                    newRow[RowIndex] = xmlRow[j].ToString().Trim();
                                    RowIndex++;
                                }
                            }

                            FileDataTable.Rows.Add(newRow);
                        }
                    
                    }


                    try
                    {
                        DataDisplayGrid.ItemsSource = FileDataTable.DefaultView;
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("This File cannot be Parsed", "Error");
                        return;
                    }

                    Datatab.IsSelected = true;
                    Datatab.IsEnabled = true;

                }



            }
            catch (Exception)
            {
                MessageBox.Show("This File Cannot be Parsed", "Error");
                return;

            }



        }

        #endregion

        #region Azure Configuration


        private void next_ConfigurationTab_Click(object sender, RoutedEventArgs e)
        {

            AccountKeyTBox.Text = System.Configuration.ConfigurationSettings.AppSettings["AccountKey"];
            AccountNameTBox.Text = System.Configuration.ConfigurationSettings.AppSettings["AccountName"];
            Configuration.IsEnabled = true;
            Configuration.IsSelected = true;
            GuidKeyRadioBtn.IsChecked = true;
            PartitionBox.Focus();
        }

        private void SeqKeyRadioBtn_Checked(object sender, RoutedEventArgs e)
        {
            SequentialKeyStackPanel.Opacity = 100;
            SeqKeyTBox.IsEnabled = true;
            SeqKeyTBox.Focus();
            SeqKeyIncrementTBox.IsEnabled = true;
        }

        private void SeqKeyRadioBtn_Unchecked(object sender, RoutedEventArgs e)
        {
            SequentialKeyStackPanel.Opacity = 0;
            SeqKeyTBox.IsEnabled = false;
            SeqKeyIncrementTBox.IsEnabled = false;
        }

        private void HeaderKeyRadioBtn_Checked(object sender, RoutedEventArgs e)
        {
            HeaderKeyStackPanel.Opacity = 100;
            HeaderNameCbox.IsEnabled = true;
            HeaderNameCbox.ItemsSource = null;
            HeaderNameCbox.ItemsSource = HeaderColumnNames;
            HeaderNameCbox.SelectedIndex = 0;
            ImportRegularHeaderChkBox.IsEnabled = true;
            HeaderNameCbox.Focus();

        }

        private void HeaderKeyRadioBtn_Unchecked(object sender, RoutedEventArgs e)
        {
            HeaderNameCbox.ItemsSource = null;
            HeaderKeyStackPanel.Opacity = 0;
            HeaderNameCbox.IsEnabled = false;
            ImportRegularHeaderChkBox.IsEnabled = false;

        }

        private void PartitionBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void GuidKeyRadioBtn_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void SeqKeyRadioBtn_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void HeaderKeyRadioBtn_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void TicksRadioBtn_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void SeqKeyTBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void SeqKeyIncrementTBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void HeaderNameCbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DisableTabItems(4);
        }

        private void ImportRegularHeaderChkBox_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(4);
        }


        #endregion

        #region Eav Generation

        private void next_EavGeneration_Click(object sender, RoutedEventArgs e)
        {

            string PartitionKey = PartitionBox.Text.ToString().Trim();
            String RowKey = String.Empty;
            String HeaderRowKey = String.Empty;
            bool headerRowKeyImportRegular = false;
            Int64 TicksNumber = DateTime.Now.Ticks;
            List<String> RowKeyList = new List<string>();
            Int64 SeqKeyNumber = 0;
            Int64 SeqKeyIncrementer = 1;

            EavTab_AccountKeyTbox.Text = AccountKeyTBox.Text.Trim();
            EavTab_AccountNameTbox.Text = AccountNameTBox.Text.Trim();
            EavTab_TableNameTbox.Text = TableNameTBox.Text.Trim();
            String ShowError = String.Empty;

            ShowError = CheckFieldErrors(out SeqKeyNumber, out SeqKeyIncrementer);
            if (ShowError.Length > 0)
            {
                MessageBox.Show(" " + ShowError, "Error");
                return;
            }

            if (HeaderKeyRadioBtn.IsChecked == true)
            {
                HeaderRowKey = HeaderNameCbox.SelectedItem.ToString();
                if (ImportRegularHeaderChkBox.IsChecked == true)
                    headerRowKeyImportRegular = true;
            }


            EavDisplayGrid.Columns.Clear();

            List<string> EavHeaderColumn = new List<string>();
            List<string> DataPresentationHeaderColumn = new List<string>();
            EavHeaderColumn.Add("PartitionKey");
            EavHeaderColumn.Add("RowKey");

            Dictionary<string, int> ColumnIndex = new Dictionary<string, int>();
            int index = 0;
            for (int i = 0; i < HeaderInformation.Length; i++)
            {

                if (HeaderInformation[i].ToBeImported)
                {
                    DataPresentationHeaderColumn.Add(HeaderInformation[i].HeaderName.ToString());
                    EavHeaderColumn.Add(HeaderInformation[i].HeaderName.ToString());
                    ColumnIndex.Add(HeaderInformation[i].HeaderName.ToString(), index++);
                }
            }
            if (!headerRowKeyImportRegular)
            {
                DataPresentationHeaderColumn.Remove(HeaderRowKey);
                EavHeaderColumn.Remove(HeaderRowKey);

            }

            EavDataTable = new DataTable();

            foreach (string EavColumnName in EavHeaderColumn)
            {
                EavDataTable.Columns.Add(EavColumnName.ToString());
            }
            EavDisplayGrid.Columns.Clear();
            EavDisplayGrid.ItemsSource = EavDataTable.DefaultView;





            int totalRow = 0;

            if (FileType == "XmlFile")
            {
                totalRow = XMlDataTable.Rows.Count;
            }
            else
            {
                totalRow = NewFile.Length;
                if (HeaderContains)
                {
                    totalRow = NewFile.Length - 1;
                }
            }


            for (int i = 0; i < totalRow; i++)
            {

                DataRow row = EavDataTable.NewRow();
                string columnValue;
                foreach (String HeaderColumn in EavHeaderColumn)
                {
                    columnValue = String.Empty;
                    if (HeaderColumn.ToString() == "PartitionKey")
                    {
                        row[HeaderColumn] = PartitionKey.ToString();
                    }
                    if (HeaderColumn.ToString() == "RowKey")
                    {
                        if (SeqKeyRadioBtn.IsChecked == true)
                        {
                            row[HeaderColumn] = SeqKeyNumber.ToString();
                            SeqKeyNumber += SeqKeyIncrementer;
                        }
                        if (HeaderKeyRadioBtn.IsChecked == true)
                        {
                            RowKey = FileDataTable.Rows[i][ColumnIndex[HeaderRowKey]].ToString();
                            if (RowKeyList.Contains(RowKey))
                            {
                                MessageBox.Show("Row Key must be unique,Please change the Header Key", "Error");
                                HeaderNameCbox.Focus();
                                return;
                            }
                            RowKeyList.Add(RowKey);
                            row[HeaderColumn] = RowKey.ToString();
                        }
                        if (GuidKeyRadioBtn.IsChecked == true)
                        {
                            row[HeaderColumn] = Guid.NewGuid().ToString();
                        }
                        if (TicksRadioBtn.IsChecked == true)
                        {
                            row[HeaderColumn] = (TicksNumber++).ToString();
                        }

                    }

                    if (DataPresentationHeaderColumn.Contains(HeaderColumn))
                    {
                        row[HeaderColumn] = FileDataTable.Rows[i][ColumnIndex[HeaderColumn]].ToString();
                    }

                }

                EavDataTable.Rows.Add(row);
            }
            EavTab.IsEnabled = true;
            EavTab.IsSelected = true;

        }

        private String CheckFieldErrors(out Int64 SeqKeyNumber, out Int64 SeqKeyIncrementer)
        {
            //Regex regex1 = new Regex("^[#?/\\]*$", RegexOptions.IgnoreCase);
            String ShowError = String.Empty;
            SeqKeyNumber = 0;
            SeqKeyIncrementer = 1;

            if (SeqKeyRadioBtn.IsChecked == true)
            {
                string SequentialKey = SeqKeyTBox.Text;
                String SeqKeyIncrement = SeqKeyIncrementTBox.Text;

                bool checkNum = false;

                checkNum = checkIsDigit(SeqKeyIncrement, out SeqKeyIncrementer);
                if (!(checkNum && SeqKeyIncrementer > 0))
                {
                    ShowError += "\n Sequential Key Incrementer must be Greater then 0 ";
                    SeqKeyIncrementTBox.Focus();
                }

                checkNum = checkIsDigit(SequentialKey, out SeqKeyNumber);
                if (!(checkNum && SeqKeyNumber >= 0))
                {
                    ShowError = "\n Sequential Key must be a Positive Number" + ShowError;
                    SeqKeyTBox.Focus();
                }
            }
            if (PartitionBox.Text.Trim().Contains("?")||PartitionBox.Text.Trim().Contains("/")||PartitionBox.Text.Trim().Contains("\\")||PartitionBox.Text.Trim().Contains("#"))
            {
                ShowError = "\n Partition Key cannot contain following symbols:\n ?  /  \\  # " + ShowError;
                PartitionBox.Focus();
            }
            if (TableNameTBox.Text.Trim() == String.Empty)
            {
                ShowError = "\n Table Name cannot be Empty " + ShowError;
                TableNameTBox.Focus();
            }
            if (AccountKeyTBox.Text.Trim() == String.Empty)
            {
                ShowError = "\n Account Key cannot be Empty " + ShowError;
                AccountKeyTBox.Focus();
            }
            if (AccountNameTBox.Text.Trim() == String.Empty)
            {
                ShowError = "\n Account Name cannot be Empty " + ShowError;
                AccountNameTBox.Focus();
            }
            return ShowError;
        }

        private bool checkIsDigit(string StringKey, out long StringNumber)
        {
            bool IsNum = Int64.TryParse(StringKey, out StringNumber);
            if (IsNum)
            {
                return true;
            }
            return false;
        }

        #endregion

        #region Upload XML

        private void NextBtn_UploadXml_Click(object sender, RoutedEventArgs e)
        {
            UploadDisplayGrid.UpdateLayout();
            go_BackBtn.IsEnabled = false;
            Start_Over.IsEnabled = false;
            UploadDataTable = new DataTable();
            UnUploadedDataTable = new DataTable();
            UploadProgressBar.Maximum = EavDataTable.Rows.Count;
            UploadProgressBar.Value = 0;
            ProgressTBox.Text = "Processing...";

            UploadTextBlock1.Text = "Uploading Progress ";

            UnUploadedDataTable = EavDataTable.Copy();

            UploadDataTable.Columns.Add("Partition Key");
            UploadDataTable.Columns.Add("Row Key");
            UploadDataTable.Columns.Add("Uploaded");
            DisableTabItems(0);
            UploadTab.IsEnabled = true;
            UploadTab.IsSelected = true;
            UploadDisplayGrid.ItemsSource = UploadDataTable.DefaultView;

            String AccountName = AccountNameTBox.Text.Trim();
            String AccountKey = AccountKeyTBox.Text.Trim();
            String EndPoint = App.EndPoint;
            String EntityXmlTemplate = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
        <entry 
                xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices"" 
                xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" 
                xmlns=""http://www.w3.org/2005/Atom"">
            <title />
            <updated>{0:yyyy-MM-ddTHH:mm:ss.fffffffZ}</updated>
            <author>
                <name />
            </author>
            <id />
            <content type=""application/xml"">
              <m:properties>
                 {1}
              </m:properties>
            </content>
        </entry>";

            String EntityPropertyTemplate =
                @"<d:{0} m:type=""Edm.{1}"">{2}</d:{0}>";

            String EntityPropertyTemplateRowKeyPartitionKey =
                 @"<d:{0}>{1}</d:{0}>";

            String EntityPropertyTemplateNull =
                 @"<d:{0} m:type=""Edm.{1}"" m:null=""true""/>";

            StringBuilder OneRowXML = new StringBuilder();
            string RowXML = String.Empty;
            int ColumnCount = EavDataTable.Columns.Count;
            int RowCount = EavDataTable.Rows.Count;
            String Message = string.Empty;
            Dictionary<String, String> HeaderDataType = new Dictionary<string, string>();



            for (int k = 0; k < HeaderInformation.Length; k++)
            {
                if (HeaderInformation[k].ToBeImported)
                {
                    HeaderDataType.Add(HeaderInformation[k].HeaderName, HeaderInformation[k].HeaderDataType);
                }
            }
            HeaderDataType.Add("PartitionKey", "String");
            HeaderDataType.Add("RowKey", "String");

            //try
            //{
            for (int i = 0; i < RowCount; i++)
            {

                DataRow row = EavDataTable.NewRow();
                UploadRow = UploadDataTable.NewRow();

                row = EavDataTable.Rows[i];

                OneRowXML.Remove(0, OneRowXML.Length);
                RowXML.Remove(0, RowXML.Length);

                for (int j = 0; j < ColumnCount; j++)
                {
                    if (j == 0 || j == 1)
                    {
                        //OneRowXML.Append(string.Format(EntityPropertyTemplateRowKeyPartitionKey, EavDataTable.Columns[j].ColumnName, row[j]));
                        OneRowXML.Append(string.Format(EntityPropertyTemplateRowKeyPartitionKey, EavDataTable.Columns[j].ColumnName, XMLSafeString(row[j].ToString())));
                        UploadRow[0] = row[0];
                        UploadRow[1] = row[1];

                    }
                    else
                    {

                        if (!string.IsNullOrEmpty(row[j].ToString()))
                            OneRowXML.Append(string.Format(EntityPropertyTemplate, EavDataTable.Columns[j].ColumnName, HeaderDataType[EavDataTable.Columns[j].ColumnName], FormatPropertyValue(HeaderDataType[EavDataTable.Columns[j].ColumnName], row[j].ToString())));
                        else
                            OneRowXML.Append(string.Format(EntityPropertyTemplateNull, EavDataTable.Columns[j].ColumnName, HeaderDataType[EavDataTable.Columns[j].ColumnName]));
                    }
                }
                RowXML = String.Format(EntityXmlTemplate, DateTime.UtcNow, OneRowXML);
                //bool flag =TableStorageRestHelper.UploadEntity(AccountName, AccountKey, TableNameTBox.Text.Trim(), DateTime.UtcNow, RowXML, out Message);
                lock (this)
                {
                    MyTaskAsync(AccountName, AccountKey, TableNameTBox.Text.Trim(), DateTime.UtcNow, RowXML, UploadRow);
                }


            }






            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show("Unable to Upload this File");
            //    return;

            //}

        }

        private object FormatPropertyValue(string PropertyType, string PropertyValue)
        {
            string ReturnPropertyValue = PropertyValue;
            try
            {
                switch (PropertyType)
                {
                    case "DateTime":
                        ReturnPropertyValue = Convert.ToDateTime(PropertyValue).ToString("yyyy-MM-ddTHH:mm:ss");
                        break;
                    case "Int32":
                        ReturnPropertyValue = Convert.ToInt32(PropertyValue).ToString();
                        break;
                    case "Int64":
                        ReturnPropertyValue = Convert.ToInt64(PropertyValue).ToString();
                        break;
                    case "Double":
                        ReturnPropertyValue = Convert.ToDouble(PropertyValue).ToString();
                        break;
                    case "Boolean":
                        ReturnPropertyValue = Convert.ToBoolean(PropertyValue).ToString();
                        break;
                    case "String":
                        ReturnPropertyValue = XMLSafeString(PropertyValue);
                        break;
                    default:
                        break;
                }

            }
            catch (Exception)
            { }
            return ReturnPropertyValue;

        }

        private string XMLSafeString(string PropertyValue)
        {
            PropertyValue = PropertyValue.Replace("&", "&amp;");
            PropertyValue = PropertyValue.Replace("<", "&lt;");
            PropertyValue = PropertyValue.Replace(">", "&gt;");
            PropertyValue = PropertyValue.Replace("\"", "&quot;");
            PropertyValue = PropertyValue.Replace("'", "&apos;");


            return PropertyValue;
        }

        private delegate bool MyTaskWorkerDelegate(string AccountName, string AccountKey, string TableName, DateTime RequestDate, string RowXML);

        public void MyTaskAsync(string AccountName, string AccountKey, string TableName, DateTime RequestDate, string RowXML, DataRow UploadRow)
        {
            //TableStorageRestHelper trh = new TableStorageRestHelper();

            MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(TableStorageRestHelper.UploadEntity);
            AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);
            AsyncOperation async = AsyncOperationManager.CreateOperation(null);
            worker.BeginInvoke(AccountName, AccountKey, TableNameTBox.Text.Trim(), DateTime.UtcNow, RowXML, completedCallback, UploadRow);

        }

        private readonly object _sync = new object();

        private int countThread = 0;

        private void MyTaskCompletedCallback(IAsyncResult ar)
        {
            // get the original worker delegate and the AsyncOperation instance
            MyTaskWorkerDelegate worker = (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;

            // finish the asynchronous operation

            DataRow Dr = (DataRow)ar.AsyncState;
            bool result = worker.EndInvoke(ar);
            countThread++;

            this.Dispatcher.Invoke(
                         System.Windows.Threading.DispatcherPriority.Normal,
                new Action(
               delegate()
               {

                   ProgressTBox.Text = ((int)(((double)countThread / (double)EavDataTable.Rows.Count) * 100)).ToString() + "% Processed.";
                   UploadProgressBar.Value = countThread;

               }));

            UIUpdate(result, Dr);
            if (result)
            {
                this.Dispatcher.Invoke(
                           System.Windows.Threading.DispatcherPriority.Normal,
                  new Action(
                 delegate()
                 {

                     DataRow[] myRow = UnUploadedDataTable.Select("RowKey='" + Dr[1].ToString() + "'");
                     if (myRow.Length > 0)
                     {
                         UnUploadedDataTable.Rows.Remove(myRow[0]);
                         UnUploadedDataTable.AcceptChanges();
                     }


                 }));

            }
            // true when all threads are completed
            if (countThread == EavDataTable.Rows.Count)
            {
                countThread = 0;

                //MessageBox.Show(countThread.ToString()+" Thread Completed");

                EavDataTable = new DataTable();
                EavDataTable = UnUploadedDataTable;

                this.Dispatcher.Invoke(
                System.Windows.Threading.DispatcherPriority.Normal,
                 new Action(
                delegate()
                {
                    Start_Over.IsEnabled = true;
                    EavDisplayGrid.ItemsSource = UnUploadedDataTable.DefaultView;
                    ProgressTBox.Text = "Processing Completed.";
                    UploadTextBlock1.Text = "Uploading Progress Completed.";
                    if (UnUploadedDataTable.Rows.Count > 0)
                    {
                        go_BackBtn.IsEnabled = true;
                    }
                }
                ));



            }

        }

        private void UIUpdate(bool result, DataRow Dr)
        {

            DataRow UploadRow = UploadDataTable.NewRow();
            UploadRow = Dr;
            if (result)
            {

                UploadDisplayGrid.Dispatcher.Invoke(
               System.Windows.Threading.DispatcherPriority.Normal,
                new Action(
               delegate()
               {
                   UploadRow[2] = "Entity Uploaded Successful";
                   UploadDataTable.Rows.Add(UploadRow);
               }
                ));

            }
            else
            {

                this.Dispatcher.Invoke(

                System.Windows.Threading.DispatcherPriority.Normal,
                 new Action(
                    delegate()
                    {

                        UploadRow[2] = "Entity Uploaded Failed";
                        UploadDataTable.Rows.Add(UploadRow);
                    }
                   ));
            }
        }





        public event AsyncCompletedEventHandler MyTaskCompleted;

        protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
        {

            if (MyTaskCompleted != null)
                MyTaskCompleted(this, e);
        }

        private void go_BackBtn_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(0);
            EavDisplayGrid.ItemsSource = EavDataTable.DefaultView;
            EavTab.IsEnabled = true;
            EavTab.IsSelected = true;
            UploadTab.IsEnabled = true;
            NextBtn_UploadXml.Content = "Reupload";
            Start_OverEavTab.IsEnabled = true;
        }

        private void Start_Over_Click(object sender, RoutedEventArgs e)
        {
            DisableTabItems(1);
            FileDelimiterStackPanel.IsEnabled = true;
            DisplayFileTextBox1.SetValue(Grid.RowProperty, 4);
            DisplayFileTextBox1.SetValue(Grid.RowSpanProperty, 1);
            FileSelectionTab.IsEnabled = true;
            FileSelectionTab.IsSelected = true;
            refreshAllTabItems();
        }

        private void refreshAllTabItems()
        {
            FileNameTextBox.Clear();
            Radioyes.IsChecked = true;
            DisplayFileTextBox1.Clear();
            delimeterCbox.SelectedIndex = 0;
            LineFeedCbox.SelectedIndex = 0;
            SkipLineCbox.SelectedIndex = 2;
            textqualifierCbox.SelectedIndex = 2;
            next_HeaderSpecificationBtn.IsEnabled = false;
            PartitionBox.Clear();
            TableNameTBox.Clear();
            SeqKeyTBox.Text = "0";
            SeqKeyIncrementTBox.Text = "1";
            GuidKeyRadioBtn.IsChecked = true;
            HeaderNameCbox.SelectedIndex = 0;
            ImportRegularHeaderChkBox.IsChecked = false;
            NextBtn_UploadXml.Content = "Upload";
            Start_OverEavTab.IsEnabled = false;
        }

        private void LaunchCloudStorageBtn_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://onlinedemo.cerebrata.com/Cerebrata.CloudStorage/default.aspx?r=FUU");
        }

        #endregion


        private void BAboutUs_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.cerebrata.com/?r=FUU");
        }

        private void BHelp_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.cerebrata.com/Docs/AzureFileUploadUtility.UserGuide.pdf");
        }

        private void DisableTabItems(int myStepNumber)
        {
            for (int i = myStepNumber; i < FileUploaderTabControl.Items.Count; i++)
                ((TabItem)FileUploaderTabControl.Items[i]).IsEnabled = false;
        }
    }
}
